package samples.groenefee;

import java.awt.*;

class PrisCanv extends Canvas implements Runnable {
    Pris00 ap;
    Thread thr = null;
    double p;
    int n;
    int[][] s;
    int[][] sn;
    int[] bc;
    double[][] pm;
    double[][] payoff;
    double b;
    Color c[][];
    int ssn[][];
    double h;
    Image im;
    Graphics gIm;
    Dimension d;
    int x, y;
    boolean painted;

    PrisCanv(Pris00 ap) {
        Color bg = new Color(255, 255, 192);
        setBackground(bg);
        this.ap = ap;
    }


    void start() {
        if (thr == null) {
            thr = new Thread(this);
            thr.start();
        }
    }

    @SuppressWarnings("deprecated")
    void stop() {
        if (thr != null) {

            thr.stop();
            thr = null;
        }
    }

    public void run() {
        initialize();
        for (; ;) {
            if (!ap.paused) {
                calculate();
                if (im == null) {
                    im = createImage(5 * n, 5 * n);
                    gIm = im.getGraphics();
                }
                {
                    for (int i = 1; i <= n; i++) {
                        for (int j = 1; j <= n; j++) {
                            gIm.setColor(c[sn[i][j]][s[i][j]]);
                            gIm.fillRect(j * 5, i * 5, 5, 5);
                            s[i][j] = sn[i][j];
                        }
                    }
                }
                painted = false;
                repaint();
                try {
                    Thread.sleep(ap.delay);
                }
                catch (InterruptedException e) {
                    ;
                }
                while (!painted) {
                    Thread.yield();
                }
            }
        }
    }

    void initialize() {
        b = ap.b;
        p = ap.p;
        n = 60;
        int bc[]; // new int[n + 1];
        double pm[][] = new double[3][3];
        pm[1][1] = 1;
        pm[1][2] = 0;
        pm[2][1] = b;
        pm[2][2] = 0;
        this.pm = pm;
        Color c[][] = new Color[3][3];
        c[1][1] = new Color(0, 0, 255);    // blue
        c[2][2] = new Color(255, 0, 0);    // red
        c[1][2] = new Color(0, 255, 0);    // green
        c[2][1] = new Color(255, 255, 0);  // yellow
        this.c = c;
        bc = setBoundary(n);
        this.bc = bc;
        s = generate(n, p);
        sn = new int[n + 1][n + 1];
        payoff = new double[61][61];
        d = getSize();
        x = (d.width / 2 - 5 * n / 2);
        y = (d.height / 2 - 5 * n / 2);
        painted = false;
    }

    public void update(Graphics g) {
        paint(g);
    }

    public void paint(Graphics g) {
        if (thr == null) {
            if (d != null) {
                g.clearRect(0, 0, d.width, d.height);
            }
            return;
        }
        painted = g.drawImage(im, x, y, null);
    }

    int[][] generate(int n, double p) {
        int s[][] = new int[n + 1][n + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                s[i][j] = 1;
                if (Math.random() < p) s[i][j] = 2;
            }
        }
        return s;
    }

    int[] setBoundary(int n) {
        int bc[] = new int[n + 2];
        for (int i = 1; i <= n; i++) {
            bc[i] = i;
        }
        bc[0] = n;
        bc[n + 1] = 1;
        return bc;
    }

    void calculate() {
        int i, j, k, l;
        double pa, hp;
        for (i = 1; i <= n; i++) {
            for (j = 1; j <= n; j++) {
                pa = 0;
                for (k = -1; k <= 1; k++) {
                    for (l = -1; l <= 1; l++) {
                        pa += pm[s[i][j]][s[bc[i + k]][bc[j + l]]];
                    }
                }
                payoff[i][j] = pa;
            }
        }

        for (i = 1; i <= n; i++) {
            for (j = 1; j <= n; j++) {
                hp = payoff[i][j];
                sn[i][j] = s[i][j];
                for (k = -1; k <= 1; k++) {
                    for (l = -1; l <= 1; l++) {
                        if (payoff[bc[i + k]][bc[j + l]] > hp) {
                            hp = payoff[bc[i + k]][bc[j + l]];
                            sn[i][j] = s[bc[i + k]][bc[j + l]];
                        }
                    }
                }
            }
        }
    }
}
